package qc.module.platform.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import qc.common.core.enums.ResourceStatusFlagEnum;
import qc.common.core.exception.QCPromptException;
import qc.common.core.tree.QCTreeNode;
import qc.common.core.unify.QCUnifyReturnValue;
import qc.module.platform.dto.dept.DeptDto;
import qc.module.platform.dto.dept.DeptSimpleDto;
import qc.module.platform.dto.dept.DeptTreeSimpleDto;
import qc.module.platform.dto.dept.DeptTreeTableDetailDto;
import qc.module.platform.entity.QcDeptUser;
import qc.module.platform.entity.QcDepts;
import qc.module.platform.mapper.DeptMapper;
import qc.module.platform.repository.QcDeptRepository;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * DeptService
 *
 * @author QuCheng Tech
 * @since 2023/5/28
 */
@Service
public class DeptService {
    private QcDeptRepository repository;
    private DeptUserService deptUserService;

    @Autowired
    public void setRepository(QcDeptRepository repository) {
        this.repository = repository;
    }

    @Autowired
    public void setDeptUserService(DeptUserService deptUserService) {
        this.deptUserService = deptUserService;
    }

    private ProjectService projectService;

    @Autowired
    public void setProjectService(ProjectService projectService) {
        this.projectService = projectService;
    }

    /**
     * 查询部门，返回简要信息；查询条件可以为空；
     *
     * @param projectCode    项目编码
     * @param includeDisable 是否包含禁用的部门
     * @param userId         用户ID，可以为null，指定用户ID后只查询用户所在的部门
     * @param isOnlyRootDept 是否只返回根部门
     * @return 部门简要信息列表
     * @author QuCheng Tech
     * @since 2023/5/28
     * @update 2024/8/2 用户ID不为空时，原来查询的是用户所在的所有部门（不分项目），修改为用户所在的当前项目所在的部门
     */
    public List<DeptDto> query(String projectCode, boolean includeDisable, int userId,boolean isOnlyRootDept) throws QCPromptException {
        if (projectCode == null)
            throw new QCPromptException("查询部门，项目编码不能为空");
        //判断有无传入用户ID查询部门
        if (userId == 0x0) {
            //查询项目中的所有部门信息
            List<QcDepts> qcDepts = getProjectAllDepts(projectCode, !includeDisable);
            List<DeptDto> dtos = DeptMapper.MAPPER.toDtoList(qcDepts);
            //为部门添加层级
            List<DeptDto> result = new ArrayList<>();
            List<DeptDto> rootDepts = getSubDepts(dtos, 0x0);
            //如果只返回根部门，直接返回
            if (isOnlyRootDept){
                return rootDepts;
            }
            for (DeptDto rootDept : rootDepts) {
                result.add(rootDept);
                addSubDepts(result, dtos, rootDept, 0x1);
            }
            //结果重新排序，先按层级，再按顺序
            //Comparator<DeptDto> levelComparator = Comparator.comparingInt(DeptDto::getLevel);
            //Collections.sort(result, levelComparator);
            //Comparator<DeptDto> idComparator = Comparator.comparingInt(DeptDto::getId);
            //Collections.sort(result, idComparator);
            return result;
        } else {
            //筛选用户部门，指定用户ID后只查询用户所在的部门
            MPJLambdaWrapper<QcDepts> wrapper = new MPJLambdaWrapper<>();
            wrapper.select(QcDepts::getId, QcDepts::getOdr, QcDepts::getName, QcDepts::getParentid, QcDepts::getFlag, QcDepts::getDescription);
            wrapper.selectAs(QcDepts::getProjectcode, DeptDto::getPcode);
            wrapper.innerJoin(QcDeptUser.class, QcDeptUser::getDeptid, QcDepts::getId);
            //是否包含禁用的部门
            if (includeDisable) {
                wrapper.eq(QcDepts::getFlag, ResourceStatusFlagEnum.NORMAL);
            }
            wrapper.eq(QcDeptUser::getUserid, userId);
            wrapper.eq(QcDepts::getProjectcode,projectCode);
            wrapper.orderByAsc(QcDepts::getOdr);
            return repository.selectJoinList(DeptDto.class, wrapper);
        }
    }

    /***
     * 获取指定项目中的所有部门，可以指定仅为有效状态或全部
     *
     * @param projectCode 项目编码
     * @param isValid 是否有效，true表示项目必须为有效状态，false表示不管项目状态是否有效
     * @return java.util.List<qc.module.platform.entity.QcDepts>
     * @author QuCheng Tech
     * @since 2023/8/31
     */
    public List<QcDepts> getProjectAllDepts(String projectCode, boolean isValid) {
        LambdaQueryWrapper<QcDepts> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(QcDepts::getProjectcode, projectCode);
        if (isValid) {
            wrapper.eq(QcDepts::getFlag, ResourceStatusFlagEnum.NORMAL);
        }

        //排序
        //wrapper.orderByAsc(QcDepts::getOdr);
        //wrapper.orderByAsc(QcDepts::getName);
        wrapper.last("order by odr asc,convert(name using gbk) asc");

        return repository.selectList(wrapper);
    }

    /***
     * 获取指定项目中指定用户关联的部门集合，可以指定仅为有效状态或全部
     *
     * @param projectCode 项目编码
     * @param userId 用户ID
     * @param isValid 是否有效，true表示项目必须为有效状态，false表示不管项目状态是否有效
     * @return java.util.List<qc.module.platform.entity.QcDepts>
     * @author QuCheng Tech
     * @since 2023/8/31
     */
    public List<QcDepts> getUserDepts(String projectCode, int userId, boolean isValid) {
        MPJLambdaWrapper<QcDepts> wrapper = new MPJLambdaWrapper<>();
        wrapper.select(QcDepts::getId, QcDepts::getOdr, QcDepts::getName, QcDepts::getParentid, QcDepts::getFlag, QcDepts::getDescription);
        wrapper.innerJoin(QcDeptUser.class, QcDeptUser::getDeptid, QcDepts::getId);
        wrapper.eq(QcDeptUser::getUserid, userId);
        wrapper.eq(QcDepts::getProjectcode, projectCode);
        //是否仅为有效状态的部门
        if (isValid)
            wrapper.eq(QcDepts::getFlag, ResourceStatusFlagEnum.NORMAL);

        wrapper.orderByAsc(QcDepts::getOdr);

        return repository.selectJoinList(QcDepts.class, wrapper);
    }

    /**
     * 为当前层级的部门添加层级关系
     *
     * @param orderByLevelDtos 添加层级属性的部门集合
     * @param allDepts         当前层级的部门集合
     * @param parentDept       当前层级的部门
     * @param level            父级层数
     */
    private void addSubDepts(List<DeptDto> orderByLevelDtos, List<DeptDto> allDepts, DeptDto parentDept, int level) {
        List<DeptDto> subDepts = getSubDepts(allDepts, parentDept.getId());
        for (DeptDto subDept : subDepts) {
            subDept.setLevel(level);
            orderByLevelDtos.add(subDept);
            addSubDepts(orderByLevelDtos, allDepts, subDept, level + 1);
        }
    }

    /**
     * 判断部门层级
     *
     * @param allDepts 部门集合
     * @param parentId 父id
     * @return 返回部门当前层级的部门集合
     */
    private List<DeptDto> getSubDepts(List<DeptDto> allDepts, int parentId) {
        return allDepts.stream().filter(dept -> dept.getParentid() == parentId).collect(Collectors.toList());
    }

    /**
     * 查询部门，返回简要信息；查询条件可以为空；
     *
     * @param projectCode    项目编码
     * @param includeDisable 是否包含禁用的部门
     * @param userId         用户ID，可以为null，指定用户ID后只查询用户所在的部门
     * @param isOnlyRootDept 是否只返回根部门
     * @return 部门简要信息列表
     * @author QuCheng Tech
     * @since 2023/5/28
     */
    public List<DeptSimpleDto> querySimpleInfoList(String projectCode, boolean includeDisable, int userId,boolean isOnlyRootDept) throws QCPromptException {
        List<DeptDto> deptDtos = query(projectCode, includeDisable, userId,isOnlyRootDept);
        return DeptMapper.MAPPER.toSimpleDtoList(deptDtos);
    }

    /***
     * 查询部门信息，以TreeTable形式返回结果
     *
     * @param projectCode 项目编码
     * @param isValid 状态是否有效
     * @param returnTreeLevel 返回层级
     * @return java.util.List<qc.module.platform.dto.dept.DeptTreeTableDetailDto>
     * @author QuCheng Tech
     * @since 2023/9/1
     */
    public List<DeptTreeTableDetailDto> queryTreeTableDetail(String projectCode, boolean isValid, int returnTreeLevel) {
        List<QcDepts> ens = getProjectAllDepts(projectCode, isValid);
        if (ens != null && ens.size() > 0x0) {
            List<DeptTreeTableDetailDto> dtos = DeptMapper.MAPPER.toTreeTableDetailDtoList(ens);

            List<DeptTreeTableDetailDto> result = new ArrayList<>();

            //获取一级部门
            List<DeptTreeTableDetailDto> rootDepts = dtos.stream().filter(p -> p.getParentid() == 0x0).collect(Collectors.toList());
            if (rootDepts != null && rootDepts.size() > 0x0) {
                //遍历一级，添加到返回集合中，获取二级
                for (DeptTreeTableDetailDto level1DeptDto : rootDepts) {
                    //设置层级
                    level1DeptDto.setLevel(0x1);
                    //判断返回树形结构需要需要获取第2级
                    if (returnTreeLevel >= 0x2) {
                        List<DeptTreeTableDetailDto> level2Depts = dtos.stream().filter(p -> level1DeptDto.getId() == (p.getParentid())).collect(Collectors.toList());
                        if (level2Depts != null && level2Depts.size() > 0x0) {
                            //遍历二级，添加到返回集合中，获取三级
                            for (DeptTreeTableDetailDto level2DeptDto : level2Depts) {
                                //设置层级
                                level2DeptDto.setLevel(0x2);
                                //判断返回树形结构需要需要获取第3级
                                if (returnTreeLevel >= 0x3) {
                                    List<DeptTreeTableDetailDto> level3Depts = dtos.stream().filter(p -> level2DeptDto.getId() == (p.getParentid())).collect(Collectors.toList());
                                    if (level3Depts != null && level3Depts.size() > 0x0) {
                                        //遍历三级，添加到返回集合中，获取四级
                                        for (DeptTreeTableDetailDto level3DeptDto : level3Depts) {
                                            //设置层级
                                            level3DeptDto.setLevel(0x3);

                                            //大于4级的暂时不进行获取，后继可进行添加
                                        }
                                        level2DeptDto.setChildren(level3Depts);
                                    }
                                }
                            }
                            level1DeptDto.setChildren(level2Depts);
                        }
                    }

                    result.add(level1DeptDto);
                }
            }

            return result;
        }

        return null;
    }

    /**
     * 获取指定部门的简要信息，返回树型结构
     * 从当前用户项目有效部门中获取
     *
     * @param deptid 部门ID
     * @param projectCode 项目编码
     * @param isValid 状态是否有效
     * @return DeptTreeSimpleDto
     * @author QuCheng Tech
     * @since 2024/6/4
     */
    public List<DeptTreeSimpleDto> getDeptTreeSimple(String projectCode,boolean isValid,Integer deptid) throws QCPromptException {
        List<DeptTreeSimpleDto> result = new ArrayList<>();
        
        List<QcDepts> ens = getProjectAllDepts(projectCode, isValid);
        if (ens != null && ens.size() > 0x0) {
            List<DeptTreeSimpleDto> dtos = DeptMapper.MAPPER.toTreeSimpleDtoList(ens);
            
            List<DeptTreeSimpleDto> rootDepts = new ArrayList<>();
            //如果有传参部门ID，根部门只有指定部门信息，否则返回所有有效部门树型集合
            if (deptid != null){
                //判断部门对象在项目有效部门中是否存在，不存在则提示
                boolean deptIsExist = dtos.stream().filter(p -> p.getId() == deptid).findAny().isPresent();
                if (!deptIsExist) throw new QCPromptException("项目有效部门信息中无当前部门信息");
                //根据部门ID查找部门信息
                DeptTreeSimpleDto dept = dtos.stream().filter(p -> p.getId() == deptid).findAny().get();
                if (Objects.nonNull(dept)){
                    rootDepts.add(dept);
                }
            }else{
                rootDepts = dtos.stream().filter(p -> p.getParentid() == 0x0).collect(Collectors.toList());
            }
            
            if (CollectionUtils.isNotEmpty(rootDepts)){
                for (DeptTreeSimpleDto rootDept : rootDepts){
                    //保存部门信息，查找子级部门
                    DeptTreeSimpleDto level1 = new DeptTreeSimpleDto();
                    level1.setId(rootDept.getId());
                    level1.setName(rootDept.getName());
                    level1.setParentid(rootDept.getParentid());
                    level1.setLevel(0x0);
                    ////获取子级
                    List<DeptTreeSimpleDto> level2Dtos = dtos.stream().filter(p -> p.getParentid() == rootDept.getId()).collect(Collectors.toList());
                    if (CollectionUtils.isNotEmpty(level2Dtos)){
                        for (DeptTreeSimpleDto level2 : level2Dtos){
                            level2.setLevel(0x1);
                            //获取子级
                            List<DeptTreeSimpleDto> level3Dtos = dtos.stream().filter(p -> p.getParentid() == level2.getId()).collect(Collectors.toList());
                            if (CollectionUtils.isNotEmpty(level3Dtos)){
                                for (DeptTreeSimpleDto level3 : level3Dtos){
                                    level3.setLevel(0x2);
                                    //获取子级
                                    List<DeptTreeSimpleDto> level4Dtos = dtos.stream().filter(p -> p.getParentid() == level3.getId()).collect(Collectors.toList());
                                    if (CollectionUtils.isNotEmpty(level4Dtos)){
                                        for (DeptTreeSimpleDto level4 : level4Dtos){
                                            level4.setLevel(0x3);
                                            //获取子级
                                            List<DeptTreeSimpleDto> level5Dtos = dtos.stream().filter(p -> p.getParentid() == level4.getId()).collect(Collectors.toList());
                                            if (CollectionUtils.isNotEmpty(level5Dtos)){
                                                for (DeptTreeSimpleDto level5 : level5Dtos){
                                                    level5.setLevel(0x4);
                                                    //
                                                }
                                                level4.setChildren(level5Dtos);
                                            }
                                        }
                                        level3.setChildren(level4Dtos);
                                    }
                                }
                                level2.setChildren(level3Dtos);
                            }
                        }
                        level1.setChildren(level2Dtos);
                    }
                    result.add(level1);
                }
            }
        }
        return result;
    }

    /**
     * 获取指定ID的栏目信息
     *
     * @param id 栏目ID
     * @return 栏目信息
     * @author QuCheng Tech
     * @since 2023/5/28
     */
    public DeptDto get(int id) throws QCPromptException {
        if (id < 0x1)
            throw new QCPromptException("部门ID无效");

        QcDepts en = repository.selectById(id);

        if (en != null)
            return DeptMapper.MAPPER.toDto(en);

        return null;
    }

    /**
     * 新增部门
     *
     * @param dto 部门信息
     * @param maxLevel 部门支持最大层级数
     * @return 成功返回null
     * @author QuCheng Tech
     * @since 2023/5/28
     */
    public String add(DeptDto dto,Integer maxLevel) {
        //1.判空
        if (dto == null)
            return QCUnifyReturnValue.Warn("部门信息不能为空");
        if (StringUtils.isBlank(dto.getName()))
            return QCUnifyReturnValue.Warn("部门名称不能为空");

        //2.当父ID大于0时
        if (dto.getParentid() > 0x0) {
            //2.1 判断父ID是否存在
            if (!hasIdExist(dto.getParentid()))
                return QCUnifyReturnValue.Warn("指定的上级部门ID不存在");

            //2.2 判断当前添加的部门是第几层级，超过支持最大层级数则提示
            Integer currentLevel = getCurrentLevel(dto.getParentid(),0x1);
            if (currentLevel > maxLevel)
                return QCUnifyReturnValue.Warn("当前只支持最多到第三级部门");
        }
        
        //3.判断项目编码是否存在
        if (!projectService.hasCodeExist(dto.getPcode()))
            return QCUnifyReturnValue.Warn("指定的项目编码不存在");

        //4.判断同一层级中部门名称不能重复
        if (hasNameExist(dto.getName(), 0x0, dto.getParentid()))
            return QCUnifyReturnValue.Warn("部门名称已存在，名称不能相同");
        
        //5.DTO转换为Entity
        QcDepts en = DeptMapper.MAPPER.DeptAddDtoToEntity(dto);

        //6.生成部门ID，获取数据库中的最大id+1后赋值
        en.setId(genereateId());

        //7.保存数据
        if (repository.insert(en) < 0x1)
            return QCUnifyReturnValue.Warn("保存失败");
        return QCUnifyReturnValue.Success();
    }

    /**
     * 计算当前添加/修改的部门所处的层级数
     * @param parentId 父ID
     * @param level 当前层级数，默认第一层(根部门)
     * @return 当前部门所处层级
     */
    private Integer getCurrentLevel(Integer parentId,Integer level){
        Integer currentLevel = level + 0x1;
        QcDepts pDept = repository.selectById(parentId);
        if (pDept.getParentid() != null && pDept.getParentid() > 0x0){
            currentLevel = getCurrentLevel(pDept.getParentid(),currentLevel);
        }
        return currentLevel;
    }

    /**
     * 修改部门
     *
     * @param dto 部门信息
     * @param maxLevel 部门支持最大层级数
     * @return 成功返回null
     * @author QuCheng Tech
     * @since 2023/5/28
     */
    public String update(DeptDto dto,Integer maxLevel) {
        //1.判空
        if (dto == null)
            return QCUnifyReturnValue.Warn("对象不能为空");
        if (dto.getId() < 0x1)
            return QCUnifyReturnValue.Warn("部门ID不能为空");
        if (StringUtils.isBlank(dto.getName()))
            return QCUnifyReturnValue.Warn("部门名称不能为空");

        //2.当父ID大于0时
        if (dto.getParentid() > 0x0) {
            //2.1 判断父ID是否存在
            if (!hasIdExist(dto.getParentid()))
                return QCUnifyReturnValue.Warn("指定的上级部门ID不存在");

            //2.2 判断当前修改的部门是第几层级，超过支持最大层级数则提示
            Integer currentLevel = getCurrentLevel(dto.getParentid(),0x1);
            if (currentLevel > maxLevel)
                return QCUnifyReturnValue.Warn("当前只支持最多到第三级部门");
            
        }

        //3.判断修改的部门是否存在
        if (!hasIdExist(dto.getId()))
            return QCUnifyReturnValue.Warn("修改的部门ID不存在");
        //4.判断名称不能重复
        if (hasNameExist(dto.getName(), dto.getId(), dto.getParentid()))
            return QCUnifyReturnValue.Warn("部门名称已存在，名称不能相同");
        

        //5.DTO转换为Entity
        QcDepts en = DeptMapper.MAPPER.DeptDtoToEntity(dto);

        //6.修改数据
        repository.updateById(en);
        return QCUnifyReturnValue.Success();
    }

    /**
     * 删除部门
     *
     * @param id            部门ID
     * @param isLogicDelete 是否为逻辑删除
     * @return 成功返回null
     * @author QuCheng Tech
     * @since 2023/5/28
     */
    public String delete(int id, boolean isLogicDelete) {
        if (id < 0x1)
            return QCUnifyReturnValue.Warn("要删除的部门ID不能为空");

        if (!hasIdExist(id))
            return QCUnifyReturnValue.Warn("要删除的部门不存在");

        if (isLogicDelete) {
            //逻辑删除，修改状态标记，不删除记录
            LambdaUpdateWrapper<QcDepts> wrapper = new LambdaUpdateWrapper<>();
            wrapper.eq(QcDepts::getId, id)
                    .set(QcDepts::getFlag, ResourceStatusFlagEnum.DELETED);

            repository.update(null, wrapper);
        } else {
            //物理删除，需要判断部门下是否有子部门
            if (getChildCount(id) > 0x0)
                return QCUnifyReturnValue.Warn("当前部门下还有子部门，无法进行删除操作");

            //删除前需先删除关联关系（部门与用户）
            deptUserService.deleteByDeptId(id);

            repository.deleteById(id);
        }

        return QCUnifyReturnValue.Success();
    }

    /**
     * 获取指定部门下的有效部门List
     * <p>
     * 获取指定部门ID下的所有部门集合，包含自己和所有子级；返回List，使用level和parentid标识层级关系；
     *
     * @param deptId 部门ID
     * @return List<DeptSimpleDto>
     * @author QuCheng Tech
     * @since 2024/11/21
     */
    public List<DeptSimpleDto> getDeptChildsList(int deptId) {
        List<DeptSimpleDto> result = new ArrayList<>();

        //此方法中的处理可以优化（减少数据库查询）修改为：根据指定的部门ID获取部门信息，在根据部门信息中的项目编码进行1次查询出项目中的所有部门，然后在代码中进行判断处理
        QcDepts dept = repository.selectById(deptId);
        if (Objects.nonNull(dept)) {
            DeptSimpleDto simpleDto = new DeptSimpleDto();
            simpleDto.setId(dept.getId());
            simpleDto.setName(dept.getName());
            if (dept.getParentid() != null && dept.getParentid() > 0x0) simpleDto.setParentid(dept.getParentid());
            simpleDto.setLevel(0x0);
            result.add(simpleDto);

            subGetDeptChildsList(deptId, result, 0x1);
        }

        return result;
    }

    /**
     * 递归获取指定部门下的所有部门集合，包含子级；返回List，使用level和parentid标识层级关系；
     *
     * @param parentId 指定部门ID
     * @param result   返回结果List
     * @param level    层级
     * @author QuCheng Tech
     * @since 2024/11/21
     */
    private void subGetDeptChildsList(int parentId, List<DeptSimpleDto> result, int level) {
        //获取指定部门的下的有效部门
        LambdaQueryWrapper<QcDepts> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(QcDepts::getParentid, parentId)
                .eq(QcDepts::getFlag, ResourceStatusFlagEnum.NORMAL)
                .orderByAsc(QcDepts::getOdr);
        List<QcDepts> ens = repository.selectList(wrapper);
        if (CollectionUtils.isNotEmpty(ens)) {
            for (QcDepts dept : ens) {
                DeptSimpleDto simpleDto = new DeptSimpleDto();
                simpleDto.setId(dept.getId());
                simpleDto.setName(dept.getName());
                simpleDto.setParentid(dept.getParentid());
                simpleDto.setLevel(level);
                result.add(simpleDto);

                subGetDeptChildsList(dept.getId(), result, level + 0x1);
            }
        }
    }

    /**
     * 获取指定部门下的有效部门Tree
     * <p>
     * 获取指定部门ID下的所有部门集合，包含自己和所有子级；返回树形结构
     *
     * @param deptId 部门ID
     * @return List<QCTreeNode>
     * @author QuCheng Tech
     * @since 2024/11/21
     */
    public List<QCTreeNode> getDeptChildsTree(int deptId) {

        List<QCTreeNode> result = new ArrayList<>();

        List<DeptSimpleDto> deptSimpleDtos = getDeptChildsList(deptId);

        //处理返回结果
        if (CollectionUtils.isNotEmpty(deptSimpleDtos)) {
            //获取第一级为自己
            DeptSimpleDto level1Dept = deptSimpleDtos.stream().filter(p -> p.getId() == deptId).findAny().orElse(null);
            if (level1Dept != null) {
                QCTreeNode level1TreeNode = new QCTreeNode();
                level1TreeNode.setKey(String.valueOf(level1Dept.getId()));
                level1TreeNode.setTitle(level1Dept.getName());
                level1TreeNode.setPid(String.valueOf(level1Dept.getParentid()));
                level1TreeNode.setLeaf(true);

                //获取下级部门
                //获取一级部门的下级部门
                List<DeptSimpleDto> level2Depts = deptSimpleDtos.stream().filter(p -> p.getParentid() == level1Dept.getId()).collect(Collectors.toList());
                if (level2Depts != null && level2Depts.size() > 0x0) {
                    level1TreeNode.setLeaf(false);
                    List<QCTreeNode> level2TreeNodes = new ArrayList<>();
                    for (DeptSimpleDto level2Dept : level2Depts) {
                        QCTreeNode level2TreeNode = new QCTreeNode();
                        level2TreeNode.setKey(String.valueOf(level2Dept.getId()));
                        level2TreeNode.setTitle(level2Dept.getName());
                        level2TreeNode.setPid(String.valueOf(level2Dept.getParentid()));
                        level2TreeNode.setLeaf(true);

                        //获取二级部门的下级部门
                        List<DeptSimpleDto> level3Depts = deptSimpleDtos.stream().filter(p -> p.getParentid() == level2Dept.getId()).collect(Collectors.toList());
                        if (level3Depts != null && level3Depts.size() > 0x0) {
                            level2TreeNode.setLeaf(false);
                            List<QCTreeNode> level3TreeNodes = new ArrayList<>();
                            for (DeptSimpleDto level3Dept : level3Depts) {
                                QCTreeNode level3TreeNode = new QCTreeNode();
                                level3TreeNode.setKey(String.valueOf(level3Dept.getId()));
                                level3TreeNode.setTitle(level3Dept.getName());
                                level3TreeNode.setPid(String.valueOf(level3Dept.getParentid()));
                                level3TreeNode.setLeaf(true);
                                
                                //可以继续获取四级级节点
                                List<DeptSimpleDto> level4Depts = deptSimpleDtos.stream().filter(p -> p.getParentid() == level3Dept.getId()).collect(Collectors.toList());
                                if (level4Depts != null && level4Depts.size() > 0x0) {
                                    level3TreeNode.setLeaf(false);
                                    List<QCTreeNode> level4TreeNodes = new ArrayList<>();
                                    for (DeptSimpleDto level4Dept : level4Depts) {
                                        QCTreeNode level4TreeNode = new QCTreeNode();
                                        level4TreeNode.setKey(String.valueOf(level4Dept.getId()));
                                        level4TreeNode.setTitle(level4Dept.getName());
                                        level4TreeNode.setPid(String.valueOf(level4Dept.getParentid()));
                                        level4TreeNode.setLeaf(true);
                                        //可以继续获取五级级节点

                                        level4TreeNodes.add(level4TreeNode);
                                    }
                                    level3TreeNode.setChildren(level4TreeNodes);
                                }
                                level3TreeNodes.add(level3TreeNode);
                            }
                            level2TreeNode.setChildren(level3TreeNodes);
                        }
                        level2TreeNodes.add(level2TreeNode);
                    }
                    level1TreeNode.setChildren(level2TreeNodes);
                }
                
                result.add(level1TreeNode);
            }
        }
        
        return result;
    }

    /**
     * 获取指定部门ID的下一级部门数量，不管下一级部门的状态
     *
     * @param id 部门ID
     * @return 下一级部门数量
     * @author QuCheng Tech
     * @since 2023/5/28
     */
    private Integer getChildCount(int id) {
        LambdaQueryWrapper<QcDepts> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(QcDepts::getParentid, id);

        Long childCount = repository.selectCount(wrapper);
        if (childCount > 0x0) {
            return childCount.intValue();
        }
        return 0x0;
    }

    /**
     * 判断指定的ID是否存在
     *
     * @param id 分类ID
     * @return true表示已存在，false表示不存在
     * @author QuCheng Tech
     * @since 2023/5/28
     */
    public boolean hasIdExist(int id) {
        LambdaQueryWrapper<QcDepts> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(QcDepts::getId);
        wrapper.eq(QcDepts::getId, id);

        QcDepts en = repository.selectOne(wrapper);
        if (en != null)
            return true;

        return false;
    }

    /**
     * 判断同一层级中部门名称是否已经存在
     * @param name 名称
     * @param id   ID，新增时设置ID为0，修改时设置ID为记录ID
     * @param pid 父id
     * @return true表示名称已存在，false表示名称不存在
     * @author QuCheng Tech
     * @since 2023/5/28
     */
    boolean hasNameExist(String name, int id,Integer pid) {
        //验证名称是否重复条件：name=name and id<>id
        LambdaQueryWrapper<QcDepts> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(QcDepts::getParentid,pid);
        wrapper.select(QcDepts::getId);
        wrapper.eq(QcDepts::getName, name);
        wrapper.ne(QcDepts::getId, id);

        QcDepts en = repository.selectOne(wrapper);
        if (en != null)
            return true;

        return false;
    }

    /**
     * 生成记录ID，获取数据库表中的最大记录ID+1
     *
     * @return 生成记录ID
     * @author QuCheng Tech
     * @since 2023/5/28
     */
    Integer genereateId() {
        Integer maxRecordId = getMaxId();
        return maxRecordId + 1;
    }

    /**
     * 获取数据库表中的最大ID值，没有记录时返回0
     *
     * @return 返回数据库表中的最大ID值
     * @author QuCheng Tech
     * @since 2023/5/28
     */
    Integer getMaxId() {
        LambdaQueryWrapper<QcDepts> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(QcDepts::getId);
        wrapper.orderByDesc(QcDepts::getId);
        QcDepts en = repository.selectOne(wrapper);
        if (en != null)
            return en.getId();

        return 0x0;
    }

    /**
     * 获取指定ID的部门实体类
     *
     * @param deptId: 部门ID
     * @return QcDepts 部门实体类
     * @author QcCheng Tech
     * @date 2023/9/15
     */
    public QcDepts getEntity(int deptId) {
        return repository.selectById(deptId);
    }

    /***
     * 获取指定部门及子级部门List
     *
     * @param deptId 指定的部门ID
     * @return java.util.List<java.lang.Integer>
     * @author QuCheng Tech
     * @since 2025/3/3
     */
    public List<Integer> getDeptChildsSimpleInfoList(int deptId) throws QCPromptException {
        QcDepts dept = getEntity(deptId);
        if (dept == null)
            throw new QCPromptException("获取指定部门及子级部门的用户信息集合时指定的部门信息不存在");
        //获取部门中的项目编码
        String projectCode = dept.getProjectcode();
        //获取项目中的所有部门
        List<QcDepts> projectAllDepts = getProjectAllDepts(projectCode, true);
        if (projectAllDepts != null && projectAllDepts.size() > 0x0) {
            return getDeptChildsSimpleInfoList(deptId, projectAllDepts);
        }

        return null;
    }

    /***
     * 从传入的部门集合中筛选出指定部门及子级部门ID集合
     *
     * @param deptId 指定的部门ID
     * @param projectAllDepts 项目所有部门集合
     * @return java.util.List<java.lang.Integer>
     * @author QuCheng Tech
     * @since 2025/3/3
     */
    public List<Integer> getDeptChildsSimpleInfoList(int deptId, List<QcDepts> projectAllDepts) {
        if (projectAllDepts != null && projectAllDepts.size() > 0x0) {
            //筛选第1级
            List<QcDepts> level1Depts = projectAllDepts.stream().filter(p -> p.getId().intValue() == deptId).collect(Collectors.toList());
            if (level1Depts != null && level1Depts.size() > 0x0) {
                List<Integer> result = new ArrayList<>();

                for (QcDepts level1Dept : level1Depts) {
                    result.add(level1Dept.getId());
                    //筛选第2级
                    List<QcDepts> level2Depts = projectAllDepts.stream().filter(p -> p.getParentid() != null && p.getParentid().intValue() == level1Dept.getId()).collect(Collectors.toList());
                    if (level2Depts != null && level2Depts.size() > 0x0) {
                        for (QcDepts level2Dept : level2Depts) {
                            result.add(level2Dept.getId());
                            //筛选第3级
                            List<QcDepts> level3Depts = projectAllDepts.stream().filter(p -> p.getParentid() != null && p.getParentid().intValue() == level2Dept.getId()).collect(Collectors.toList());
                            if (level3Depts != null && level3Depts.size() > 0x0) {
                                for (QcDepts level3Dept : level3Depts) {
                                    result.add(level3Dept.getId());
                                    //筛选第4级
                                    List<QcDepts> level4Depts = projectAllDepts.stream().filter(p -> p.getParentid() != null && p.getParentid().intValue() == level3Dept.getId()).collect(Collectors.toList());
                                    if (level4Depts != null && level4Depts.size() > 0x0) {
                                        for (QcDepts level4Dept : level4Depts) {
                                            result.add(level4Dept.getId());
                                            //筛选第5级
                                            List<QcDepts> level5Depts = projectAllDepts.stream().filter(p -> p.getParentid() != null && p.getParentid().intValue() == level4Dept.getId()).collect(Collectors.toList());
                                            if (level5Depts != null && level5Depts.size() > 0x0) {
                                                for (QcDepts level5Dept : level5Depts) {
                                                    result.add(level5Dept.getId());
                                                    //需要继续往下一级筛选可以继续在此添加
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                return result;
            }
        }

        return null;
    }

    /***
     * 根据关联的部门ID得到有访问权限的所有部门ID集合，直接关联的部门及子级部门均有访问权限
     *
     * @param relatedDeptIds 直接关联的部门ID集合
     * @param projectAllDepts 项目中的所有部门集合
     * @return java.util.List<java.lang.Integer>
     * @author QuCheng Tech
     * @since 2025/3/3
     */
    public List<Integer> getCanAccessDeptIds(List<Integer> relatedDeptIds, List<QcDepts> projectAllDepts) throws QCPromptException {
        if (relatedDeptIds != null && relatedDeptIds.size() > 0x0 && projectAllDepts != null && projectAllDepts.size() > 0x0) {
            //传入的项目中所有部门集合不一定包含父部门为空的，也可能存在传入的部门最上级不是根部门的情况;此种情况暂时不考虑
            //筛选第1级
            List<QcDepts> level1Depts = projectAllDepts.stream().filter(p -> p.getParentid() == null || p.getParentid().intValue() < 0x1).collect(Collectors.toList());
            if (level1Depts != null && level1Depts.size() > 0x0) {
                List<Integer> result = new ArrayList<>();

                for (QcDepts level1Dept : level1Depts) {
                    result.add(level1Dept.getId());
                    //筛选第2级
                    List<QcDepts> level2Depts = projectAllDepts.stream().filter(p -> p.getParentid() != null && p.getParentid().intValue() == level1Dept.getId()).collect(Collectors.toList());
                    if (level2Depts != null && level2Depts.size() > 0x0) {
                        for (QcDepts level2Dept : level2Depts) {
                            result.add(level2Dept.getId());
                            //筛选第3级
                            List<QcDepts> level3Depts = projectAllDepts.stream().filter(p -> p.getParentid() != null && p.getParentid().intValue() == level2Dept.getId()).collect(Collectors.toList());
                            if (level3Depts != null && level3Depts.size() > 0x0) {
                                for (QcDepts level3Dept : level3Depts) {
                                    result.add(level3Dept.getId());
                                    //筛选第4级
                                    List<QcDepts> level4Depts = projectAllDepts.stream().filter(p -> p.getParentid() != null && p.getParentid().intValue() == level3Dept.getId()).collect(Collectors.toList());
                                    if (level4Depts != null && level4Depts.size() > 0x0) {
                                        for (QcDepts level4Dept : level4Depts) {
                                            result.add(level4Dept.getId());
                                            //筛选第5级
                                            List<QcDepts> level5Depts = projectAllDepts.stream().filter(p -> p.getParentid() != null && p.getParentid().intValue() == level4Dept.getId()).collect(Collectors.toList());
                                            if (level5Depts != null && level5Depts.size() > 0x0) {
                                                for (QcDepts level5Dept : level5Depts) {
                                                    result.add(level5Dept.getId());
                                                    //需要继续往下一级筛选可以继续在此添加
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                return result;
            } else {
                throw new QCPromptException("获取有访问权限的所有部门ID集合时无根部门信息");
            }
        }

        return null;
    }
}